package com.originskyseed.platform.common.api.util;

import com.originskyseed.platform.core.redis.util.RedisUtil;
import org.springframework.data.redis.core.RedisCallback;

import java.util.Objects;

public class DistributedLockUtil {
    /**
     * 加锁
     * @param lockName
     * @param timeout
     * @return
     */
    public static boolean lock(String lockName,int timeout) {
        return (boolean)  RedisUtil.getInstance().getRedisTemplate().execute((RedisCallback) connection -> {
            //获取时间毫秒值
            long expireAt = System.currentTimeMillis() + timeout + 1;
            //获取锁
            Boolean acquire = connection.setNX(lockName.getBytes(), String.valueOf(expireAt).getBytes());
            if (acquire) {
                return true;
            } else {
                byte[] bytes = connection.get(lockName.getBytes());
                //非空判断
                if (Objects.nonNull(bytes) && bytes.length > 0) {
                    long expireTime = Long.parseLong(new String(bytes));
                    // 如果锁已经过期
                    if (expireTime < System.currentTimeMillis()) {
                        // 重新加锁，防止死锁
                        byte[] set = connection.getSet(lockName.getBytes(), String.valueOf(System.currentTimeMillis() + timeout + 1).getBytes());
                        return Long.parseLong(new String(set)) < System.currentTimeMillis();
                    }
                }
            }
            return false;
        });
    }

    /**
     * 释放锁
     * @param lockName
     * @return
     */
    public static void delete(String lockName) {
        Object lockObj = RedisUtil.getInstance().hasKey(lockName);
        if (lockObj != null) {
            RedisUtil.getInstance().delete(lockName);
        }
    }
}
